import {
  destroyLayer,
  entityEffectClickCallback,
  fakeparticleSystemEffectClickCallback,
  getLayerMap,
  gltfmodeleffectClickCallback,
  poiClickCallback,
  regionEffectClickCallback,
  roadEffectClickCallback,
} from '@/service';
import { deletelayerRequestIns } from '@/service/effect';
import { useSceneStore } from '@/store/scene';
import { deleteTreeNode } from '@/utils';
import { round } from 'lodash';

const sceneStore = useSceneStore();

/**
 * 删除图层
 */
export const deleteLayer = (layer: API.Scene.ILayer) => {
  const { cimInstance } = window;
  const layerMap = getLayerMap();
  const layerIndex = sceneStore.layerList.findIndex(
    (item: API.Scene.ILayer) => item.type === layer.type && item.layerName === layer.layerName
  );
  if (
    layer.code &&
    ['gltfmodel', 'fake_particleSystem', 'entity', 'bimModel', 'tileset', 'drawlabel'].includes(
      layer.type
    ) &&
    sceneStore.selLayer &&
    sceneStore.selLayer.code === layer.code
  ) {
    cimInstance.api.changeOrbitControlMode('');
    cimInstance.api.deleteOrbitControl(layer.layerName);
  }
  if (['tileset'].includes(layer.type)) {
    cimInstance.api.changeOrbitControlMode('');
    cimInstance.api.deleteOrbitControl(layer.layerName);
  }
  // 路径和区域轮廓退出编辑模式
  if (['road', 'regionEffect'].includes(layer.type)) {
    cimInstance.api.cancelEdit();
  }
  // jlg 移除鼠标监听事件
  if (layer.type === 'bimModel') {
    const { cimInstance } = window;
    cimInstance.api.changeOrbitControlMode('none');
  }
  // 取消在线地图
  if (layer.type === 'imageLayer') {
    const index = sceneStore.onlineMapSels.findIndex((item: string) => item === layer.json.name);
    sceneStore.onlineMapSels.splice(index, 1);
  }
  if (layer.type === 'terrain') {
    sceneStore.activeTerrains = sceneStore.activeTerrains.filter(
      (item: string) => item !== layer.json.name
    );
  }
  if (
    layer.type === 'div' &&
    sceneStore.divEditLayerName &&
    layer.layerName === sceneStore.divEditLayerName
  ) {
    sceneStore.divEditLayerName = '';
  }
  destroyLayer(layer);
  deletelayerRequestIns(layer);
  if (sceneStore.selLayer && sceneStore.selLayer.layerName === layer.layerName) {
    sceneStore.specialEffectVisible = false;
    sceneStore.selLayer = null;
    sceneStore.selectedLayerNode = null;
  }
  sceneStore.layerList.splice(layerIndex, 1);
  layerMap.delete(layer.code);
};

/**
 *
 * @param layer 删除图层树节点
 */
export const deleteTreeData = (layer: any) => {
  deleteTreeNode(sceneStore.layerTree, layer.id, {
    id: 'fe_id',
  });
};

/**
 * 初始化化三叉轴
 */
export const initTridentEvent = (layer: API.Scene.ILayer) => {
  const { cimInstance } = window;
  if (['gltfmodel'].includes(layer.type)) {
    if (layer.actualType === 'gltfmodeleffect') {
      gltfmodeleffectClickCallback({
        code: 'effect',
        clickObject: {
          id: layer.layerName,
        },
      });
      return;
    }
    cimInstance.api.setLayerOrbitControl(layer.layerName, updateAttrCallback);
    cimInstance.api.changeOrbitControlMode('translation');
  } else if (['entity'].includes(layer.type)) {
    entityEffectClickCallback({
      code: 'effect',
      clickObject: {
        id: layer.layerName,
      },
    });
  } else if (['road'].includes(layer.type)) {
    roadEffectClickCallback({
      code: 'effect',
      clickObject: {
        id: layer.layerName,
      },
    });
  } else if (['fake_particleSystem'].includes(layer.type)) {
    fakeparticleSystemEffectClickCallback({
      code: 'effect',
      clickObject: {
        id: layer.layerName,
      },
    });
  } else if (['drawlabel'].includes(layer.type)) {
    poiClickCallback({
      code: 'effect',
      clickObject: {
        id: '0_image',
        name: 'poi_0_image',
        layerName: layer.layerName,
      },
    });
  } else if (['tileset'].includes(layer.type)) {
    const attr: any = {
      rotation: [0, 0, 0],
      offset: [0, 0, 0],
      ...layer?.attr,
    };
    if (!attr?.material) {
      attr.material = {
        brightness: 1,
        contrast: 1,
        hue: 0,
        saturation: 1,
        gamma: 1,
      };
    }
    layer.attr = attr;
    cimInstance.api.setLayerOrbitControl(layer.layerName, updateAttrCallback);
    cimInstance.api.changeOrbitControlMode('translation');
  } else if (layer.type === 'bimModel') {
    const attr: any = {
      position: [],
      translation: [0, 0, 0],
      rotation: [0, 0, 0],
      ...layer?.attr,
    };
    layer.attr = attr;
    cimInstance.api.setLayerOrbitControl(layer.layerName, updateAttrCallback);
    cimInstance.api.changeOrbitControlMode('translation');
  } else if (layer.type === 'image') {
    layer.attr = {};
  } else if (['regionEffect'].includes(layer.type)) {
    regionEffectClickCallback({
      code: 'effect',
      clickObject: {
        id: layer.layerName,
      },
    });
  }
};

/**
 * 键盘三轴监听回调更新属性值
 */
function updateAttrCallback(backAttr: any) {
  const layer = sceneStore.selLayer;
  if (!layer) {
    return;
  }
  const { cimInstance } = window;
  if (!layer.attr) {
    layer.attr = {};
  }
  const config = cimInstance.api.getCurrentLayerConfig(layer.layerName);
  if (config?.scale) {
    layer.attr.scale = config.scale;
    layer.attr.scaleData = config.scale * 100;
  }
  if (config?.rotation) {
    layer.attr.rotation = [
      round(config.rotation[0], 2),
      round(config.rotation[1], 2),
      round(config.rotation[2], 2),
    ];
  }
  // 平移数据 gltf 和 osgb(3dtiles) 是在图层配置的translation, jlg模型是在图层的配置参数offset中
  if (['gltfmodel', 'tileset'].includes(layer.type)) {
    if (config?.translation) {
      layer.attr.translation = [
        round(config.translation[0], 2),
        round(config.translation[1], 2),
        round(config.translation[2], 2),
      ];
    }
  }
  if (['bimModel'].includes(layer.type)) {
    if (config?.offset) {
      layer.attr.translation = [
        round(config.offset[0], 2),
        round(config.offset[1], 2),
        round(config.offset[2], 2),
      ];
    }
  }
}

/**
 *
 * @param layerType 图层类型
 * @param layerActualType 图层实际类型
 * @param panelCompName 面板组件名称
 * @returns
 */
export const generateListLayerName = (
  layerType: API.Scene.LayerType,
  layerActualType?: API.Scene.LayerActualType,
  panelCompName?: string
) => {
  const { layerList } = sceneStore;
  if (layerType === 'road') {
    const nums = layerList
      .map((v: API.Scene.ILayer) => {
        const replaceData = Number(v.name.replace(/^Path/, ''));
        return isNaN(replaceData) ? 0 : replaceData;
      })
      .sort((a: number, b: number) => b - a);
    return `Path${nums.length ? nums[0] + 1 : 1}`;
  }
  if (layerType === 'regionEffect') {
    const nums = layerList
      .map((v: API.Scene.ILayer) => {
        const replaceData = Number(v.name.replace(/^Outline/, ''));
        return isNaN(replaceData) ? 0 : replaceData;
      })
      .sort((a: number, b: number) => b - a);
    return `Outline${nums.length ? nums[0] + 1 : 1}`;
  }
  if (layerType === 'drawlabel') {
    const nums = layerList
      .map((v: API.Scene.ILayer) => {
        const replaceData = Number(v.name.replace(/^POI/, ''));
        return isNaN(replaceData) ? 0 : replaceData;
      })
      .sort((a: number, b: number) => b - a);
    return `POI${nums.length ? nums[0] + 1 : 1}`;
  }
  if (
    (layerType === 'gltfmodel' && layerActualType && layerActualType === 'gltfmodeleffect') ||
    ['fake_particleSystem', 'entity'].includes(layerType)
  ) {
    const nums = layerList
      .map((v: API.Scene.ILayer) => {
        const replaceData = Number(v.name.replace(/^Effect/, ''));
        return isNaN(replaceData) ? 0 : replaceData;
      })
      .sort((a: number, b: number) => b - a);
    return `Effect${nums.length ? nums[0] + 1 : 1}`;
  }
  if (layerType === 'div') {
    const regx = new RegExp(`^${panelCompName}`);
    const nums = layerList
      .map((v: API.Scene.ILayer) => {
        const replaceData = Number(v.name.replace(regx, ''));
        return isNaN(replaceData) ? 0 : replaceData;
      })
      .sort((a: number, b: number) => b - a);
    return `${panelCompName}${nums.length ? nums[0] + 1 : 1}`;
  }
  return '';
};
